#!/usr/bin/python
#
#

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from reportlab.lib.colors import black, white, gray, lightgrey,  darkgray,  red 
from reportlab.lib.pagesizes import letter
from reportlab.platypus.tables import LINECAPS

from sys import argv

from unit import Unit

pdfmetrics.registerFont(TTFont('LS_B', 'fonts/LiberationSans-Bold.ttf'))
pdfmetrics.registerFont(TTFont('LS_BI', 'fonts/LiberationSans-BoldItalic.ttf'))
pdfmetrics.registerFont(TTFont('LS_I', 'fonts/LiberationSans-Italic.ttf'))
pdfmetrics.registerFont(TTFont('LS', 'fonts/LiberationSans-Regular.ttf'))
pdfmetrics.registerFont(TTFont('RET', 'fonts/Retriga.ttf'))

''' 
    Parse the input .csv file as a list of weapons (one per line)
    and construct a data object for later consumption
'''
def parseList(srcF):
    units = {}
    for rawline in srcF:
        line = rawline.strip()
        if line == "": 
            continue
        tmp = line.replace(",", "")
        if tmp == "":
            continue
        tmp = line.replace("\"\"", "")

        unit = Unit()
        unit.parse(tmp)
        unit.printDetails()

        
    return units

'''
    Parse a line of csv text assuming a common format
    into a dict that contains the keys we need to 
    print the chart
'''
def parseLine(tokens, traits):
    if len(tokens) < 20:
        print "Not enough data, skipping"

    weapon = {}
    weapon["code"] = tokens[0]
    weapon["hgCode"] = tokens[1]
    weapon["range"] = tokens[3]
    weapon["bd"] = tokens[5]
    weapon["dm"] = tokens[8]
    weapon["ae"] = tokens[10]
    if (weapon["ae"] == "" or weapon["ae"] == 0):
        weapon["ae"] = "-"
    else:
        weapon["ae"] = "%s\"" % weapon["ae"]

    # Check for split traits
    if traits == "":
        weapon["traits"] = tokens[12]
    else:
        weapon["traits"] = traits
    if weapon["traits"] == "":
        weapon["traits"] = "-"

    weapon["type"] = tokens[13]
    weapon["order"] = tokens[14]
    weapon["ammo"] = tokens[15]
    if (weapon["ammo"] == "" or weapon["ammo"] == 0):
        weapon["ammo"] = "-"
    else:
        tmp = "O" * int(weapon["ammo"])
        weapon["ammo"] = tmp

    print "Weapon is %s" % weapon
    return weapon


def writeChart(category, weapons, c, lineY, config):
    if (len(weapons) == 0):
        return

    if (lineY == 0): 
        lineY = letter[1] - config["margin"]
    else:
        lineY = lineY - config["categoryFontSize"]

    # Estimate if we should skip a page
    # 1.3 is our guesstimate for spacing, etc
    estNumPoints = (len(weapons) * config["fontSize"] * 1.3)
    print "Estimated points is %2.3f, delta is %2.3f" % (estNumPoints, (lineY - estNumPoints))
    if ((lineY - estNumPoints) <= 0):
        c.showPage()
        lineY = letter[1] - config["margin"]
    

    # Write the category & header
    c.setFont("RET", config["categoryFontSize"])
    c.drawString(config["margin"], lineY, category)
    c.line(config["margin"], lineY-2, letter[0] - config["margin"], lineY - 2);
    lineY = lineY - config["categoryFontSize"]

    lineY = writeHeaderLine(c, lineY, config)

    numPoints = config["maxPoints"]
    lastCode = ""
    for weapon in weapons:
    
        if category != "MELEE" and category != "THROWN" and category != "INFANTRY":   
            code = weapon["code"]
            #print "raw code is: [%s]" % (code),
            # If the weapon starts with V, take everything after 2
            if code.endswith("RP/",0,-1):
                code = code[:-2]
            elif code.startswith("V") or code.startswith("AP"):
                code = code[2:]
            else:
                code = code[1:]

            if not code == lastCode:
                #print "Changed weapons, skipping a space"
                numPoints = numPoints - 4
                lineY = lineY - 4
            lastCode = code
        else:
            lineY = lineY - 4

        #print "Weapon is %s" % weapon
        writeWeaponLine(c, weapon, lineY, config)
        lineY = lineY - config["fontSize"]
        numPoints = numPoints - config["fontSize"]

    return lineY 
        

def writeHeaderLine(canvas, y, config):
    marginX = config["margin"]
    fontSize = config["fontSize"]

    canvas.setStrokeColor(gray)
    canvas.setFillColor(gray)
    canvas.setFont("LS_B", fontSize)
    canvas.drawString(marginX + 10, y, "CODE")
    canvas.drawString(marginX + 60, y, "HGB")

    canvas.drawRightString(marginX + 125, y, "RNG")

    canvas.drawRightString(marginX + 160, y, "BD")
    canvas.drawString(marginX + 165, y, "DM")

    canvas.drawCentredString(marginX + 200, y, "AE")

    canvas.drawString(marginX + 220, y, "TRAITS")
    canvas.drawString(marginX + 380, y, "TYPE")

    canvas.drawString(marginX + 440, y, "AMMO")

    canvas.line(marginX + 6, y-2, letter[0] - marginX, y-2)

    canvas.setStrokeColor(black)
    canvas.setFillColor(black)
    return y-8


def writeWeaponLine(canvas, weapon, y, config):
    marginX = config["margin"]
    fontSize = config["fontSize"]

    canvas.setFont("LS_B", fontSize)
    canvas.drawString(marginX + 10, y, weapon["code"])

    canvas.setFont("LS", fontSize)
    canvas.drawString(marginX + 60, y, weapon["hgCode"])

    canvas.setFont("LS", fontSize)
    canvas.drawRightString(marginX + 125, y, "%s\"" % weapon["range"])

    canvas.drawRightString(marginX + 158, y, weapon["bd"])

    canvas.setFont("LS_B", fontSize)
    canvas.drawString(marginX + 167, y, "x" + weapon["dm"])

    canvas.setFont("LS", fontSize)
    canvas.drawCentredString(marginX + 200, y, weapon["ae"])

    canvas.setFont("LS_I", fontSize)
    canvas.drawString(marginX + 220, y, weapon["traits"])

    canvas.setFont("LS", fontSize)
    canvas.drawString(marginX + 380, y, weapon["type"])
    canvas.drawString(marginX + 440, y, weapon["ammo"])


if __name__ == '__main__':

    src = "units.csv"
    if (len(argv) > 1):
        src = argv[1]
    srcF = open(src, 'r')
    units = parseList(srcF); 
    srcF.close()

    c = canvas.Canvas("units.pdf", pagesize=letter)
    c.setStrokeColor(black)
    config = {
        "margin" :20,
        "fontSize" : 10,
        "categoryFontSize" : 16,
        "maxPoints" : int((letter[1] - 20 * 2))
    }
    
    '''
    writeChart(units, c, lineY, config)
    '''
    c.save() 

